package com.sheng.leetcode.year2023.month10.day11;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author by ls
 * @date 2023/10/11
 * <p>
 * 2512. 奖励最顶尖的 K 名学生<p>
 * <p>
 * 给你两个字符串数组 positive_feedback 和 negative_feedback ，分别包含表示正面的和负面的词汇。不会 有单词同时是正面的和负面的。
 * 一开始，每位学生分数为 0 。每个正面的单词会给学生的分数 加 3 分，每个负面的词会给学生的分数 减  1 分。
 * 给你 n 个学生的评语，用一个下标从 0 开始的字符串数组 report 和一个下标从 0 开始的整数数组 student_id 表示，
 * 其中 student_id[i] 表示这名学生的 ID ，这名学生的评语是 report[i] 。每名学生的 ID 互不相同。
 * 给你一个整数 k ，请你返回按照得分 从高到低 最顶尖的 k 名学生。如果有多名学生分数相同，ID 越小排名越前。<p>
 * <p>
 * 示例 1：<p>
 * 输入：positive_feedback = ["smart","brilliant","studious"],<p>
 * negative_feedback = ["not"],<p>
 * report = ["this student is studious","the student is smart"],<p>
 * student_id = [1,2], k = 2<p>
 * 输出：[1,2]<p>
 * 解释：<p>
 * 两名学生都有 1 个正面词汇，都得到 3 分，学生 1 的 ID 更小所以排名更前。<p>
 * <p>
 * 示例 2：<p>
 * 输入：positive_feedback = ["smart","brilliant","studious"],<p>
 * negative_feedback = ["not"],<p>
 * report = ["this student is not studious","the student is smart"],<p>
 * student_id = [1,2], k = 2<p>
 * 输出：[2,1]<p>
 * 解释：<p>
 * - ID 为 1 的学生有 1 个正面词汇和 1 个负面词汇，所以得分为 3-1=2 分。<p>
 * - ID 为 2 的学生有 1 个正面词汇，得分为 3 分。<p>
 * 学生 2 分数更高，所以返回 [2,1] 。<p>
 * <p>
 * 提示：<p>
 * 1 <= positive_feedback.length, negative_feedback.length <= 10^4<p>
 * 1 <= positive_feedback[i].length, negative_feedback[j].length <= 100<p>
 * positive_feedback[i] 和 negative_feedback[j] 都只包含小写英文字母。<p>
 * positive_feedback 和 negative_feedback 中不会有相同单词。<p>
 * n == report.length == student_id.length<p>
 * 1 <= n <= 10^4<p>
 * report[i] 只包含小写英文字母和空格 ' ' 。<p>
 * report[i] 中连续单词之间有单个空格隔开。<p>
 * 1 <= report[i].length <= 100<p>
 * 1 <= student_id[i] <= 10^9<p>
 * student_id[i] 的值 互不相同 。<p>
 * 1 <= k <= n<p>
 */
public class LeetCode2512 {

    @Test
    public void test01() {
//        String[] positive_feedback = {"smart", "brilliant", "studious"}, negative_feedback = {"not"}, report = {"this student is studious", "the student is smart"};
//        int[] student_id = {1, 2};
//        int k = 2;
        String[] positive_feedback = {"smart", "brilliant", "studious"}, negative_feedback = {"not"}, report = {"this student is not studious", "the student is smart"};
        int[] student_id = {1, 2};
        int k = 2;
        System.out.println(new Solution().topStudents(positive_feedback, negative_feedback, report, student_id, k));
    }
}

class Solution {
    public List<Integer> topStudents(String[] positive_feedback, String[] negative_feedback, String[] report, int[] student_id, int k) {
        // positive_feedback：正面词汇（加三分）
        // negative_feedback：负面词汇（减一分）
        // 注：positive_feedback 和 negative_feedback 内的词汇可能重复，需要过滤
        Set<String> positiveFeedback = Arrays.stream(positive_feedback).collect(Collectors.toSet());
        Set<String> negativeFeedback = Arrays.stream(negative_feedback).collect(Collectors.toSet());
        int n = report.length;
        // 创建长度为 n 的二维数组，第一个元素代表学生 id，第二个元素代表学生得分
        int[][] ints = new int[n][2];
        for (int i = 0; i < n; i++) {
            int score = 0;
            for (String s : report[i].split(" ")) {
                // 判断当前词汇的正面还是负面
                if (positiveFeedback.contains(s)) {
                    score += 3;
                } else if (negativeFeedback.contains(s)) {
                    score -= 1;
                }
            }
            ints[i][0] = student_id[i];
            ints[i][1] = score;
        }
        // 对学生编号和得分进行排序
        Arrays.sort(ints, (o1, o2) -> o1[1] == o2[1] ? o1[0] - o2[0] : o2[1] - o1[1]);
        List<Integer> list = new ArrayList<>();
        // 获取前 k 名学生
        for (int i = 0; i < k; i++) {
            list.add(ints[i][0]);
        }
        return list;
    }
}
